/**************************************

    author  : xy_god
    e-mail  : xy_god@thesct.net
    homepage: http://www.thesct.net

    FileName: xmem_pool.c
    gen_time: 2014.10.13

    comments:
        该文件定义了内存池的所具有的相应
    操作.

 **************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xbase.h"
#include "xmem_pool.h"

//-------------------------------- start --------------------------------

// 获取内存列表中的有效个数
inline int get_list_num(x_mem_block_t *p_block)
{
  int n = 0;
  memcpy(&n,p_block->unit_array[0],sizeof(int));
  return n;
}

// 获取内存列表中的有效个数
inline void set_list_num(x_mem_block_t *p_block,int n)
{
  memcpy(p_block->unit_array[0], &n, sizeof(int));
  return;
}

// 获取内存列表节点中的地址
inline void *get_node_addr(x_mem_block_t *p_block, int n)
{
  void * addr = NULL;
  memcpy(&addr,p_block->unit_array[n], sizeof(void*));
  return addr;
}

// 设定内存列表节点中的地址
inline void set_node_addr(x_mem_block_t *p_block, int n, void *val)
{
  void * new_val = val;
  memcpy(p_block->unit_array[n],&new_val, sizeof(void*));
  return;
}

// 向在用或者空闲内存链表中增加节点
int mem_list_add(x_mem_pool_t *p_mem_pool, // 内存池对象
                 int i_list_type,          // 内存链表类型:0,空闲:1,在用.
                 void * p_addr_req,        // 请求的内存地址
                 int i_unit_number_req)    // 请求的内存单元数
{
    int i_err = 0;

    x_mem_block_t *p_list = NULL;
    x_mem_block_t *p_list_tail = NULL;
    x_mem_block_t *p_list_temp = NULL;

    x_mem_block_t *p_mem_list = NULL;

    // 参数合法性检测
    if (p_mem_pool == NULL)                // 如果内存池对象不存在
        { i_err = ERR_MP_PARAM; goto error_tray; }
    if (i_unit_number_req <= 0)            // 请求的内存单元数量小于0
        { i_err = ERR_MP_PARAM; goto error_tray; }
    if (i_unit_number_req > UNIT_NUMBER)   // 请求的内存单元数大于UNIT_NUMBER
        { i_err = ERR_MP_PARAM; goto error_tray; }
    switch (i_list_type){                  // 内存链表类型检测
    case 0:
	  p_mem_list = p_mem_pool->p_mem_free_list;
        break;
    case 1:
        p_mem_list = p_mem_pool->p_mem_used_list;
        break;
    default:
        { i_err = ERR_MP_PARAM; goto error_tray; }        
    }
    
    // 取得对应内存单元数的空闲内存链表头
	p_list = (x_mem_block_t*)get_node_addr(p_mem_list, i_unit_number_req -1);
    if (p_list == NULL){
        p_list = (x_mem_block_t*)mallocs(sizeof(x_mem_block_t));
        if (p_list == NULL) { i_err = ERR_MP_NOMEM; goto error_tray; }
        p_list->p_next = NULL;
		set_list_num(p_list, 0);
		set_node_addr(p_mem_list, i_unit_number_req - 1, p_list);
    }

    // 取得空闲内存链表尾
    p_list_tail = p_list;
    while(p_list_tail->p_next != NULL) {
        p_list_tail = p_list_tail->p_next;
    }
    if (get_list_num(p_list_tail) == (UNIT_NUMBER - 1)) {
        p_list_temp = (x_mem_block_t*)mallocs(sizeof(x_mem_block_t));
        if (p_list_temp == NULL) 
            { i_err = ERR_MP_NOMEM; goto error_tray;}
		set_list_num(p_list, 0);
        p_list_temp->p_next = NULL;
        p_list_tail->p_next = p_list_temp;
        p_list_tail = p_list_temp;
    }

	set_list_num(p_list_tail, get_list_num(p_list_tail) + 1);
	set_node_addr(p_list_tail, get_list_num(p_list_tail), p_addr_req);

    return 0;
 error_tray: // 错误处理
    fprintf(stderr,                        // 错误输出
            "mem_list_add 中发生错误,错误号: [ %d ].", i_err);
    return i_err;
}

// 从在用或者空闲内存链表中删除节点
int mem_list_del(x_mem_pool_t *p_mem_pool, // 内存池对象
                 int i_list_type,          // 内存链表类型:0,空闲:1,在用.
                 void * p_addr_req)        // 请求的内存地址
{
    int i_err = 0;
    int i = 0;
    int k = 0;
    int m = 0;
    int i_start = 0;
    int i_flag = 0;                        // 查找结果标识:0,未找到;1,找到.

    x_mem_block_t *p_list = NULL;
    x_mem_block_t *p_list_pre = NULL;
    x_mem_block_t *p_list_tail = NULL;
    x_mem_block_t *p_list_last = NULL;

    x_mem_block_t *p_mem_list = NULL;

    // 参数合法性检测
    if (p_mem_pool == NULL)                // 如果内存池对象不存在
        { i_err = ERR_MP_PARAM; goto error_tray; }
    switch (i_list_type){                  // 内存链表类型检测
    case 0:
        p_mem_list = p_mem_pool->p_mem_free_list;
        break;
    case 1:
	  p_mem_list = p_mem_pool->p_mem_used_list;
        break;
    default:
        { i_err = ERR_MP_PARAM; goto error_tray; }        
    }

    // 遍历所有内存链表,查找相应的项
    i_flag = 0;                           // 查找结果,未找到
    for (i = 0; i < UNIT_NUMBER;i++){
	  p_list = (x_mem_block_t*)get_node_addr(p_mem_list, i);
      p_list_pre = NULL;
      while(p_list != NULL){            // 遍历内存链表
		if( get_list_num(p_list) > 0){// 如果该节点有效
		  for(k = 1; k <= (get_list_num(p_list)); k++){
			if (get_node_addr(p_list, k) == p_addr_req) {
			  i_flag = 1;
			  goto normal_continue;
			}
		  }
		}
		p_list_pre = p_list;
		p_list = p_list->p_next;
      }
    }
    //	printf("testing : 4\r\n");
 normal_continue:
    if (i_flag == 0){                     // 未找到
        i_err = ERR_MP_NOOBJ; goto error_tray;
    } else {                              // 已找到
	  set_list_num(p_list,get_list_num(p_list) - 1);
	  if (get_list_num(p_list) <= 0) { // 节点已空
		// 删除该节点
		if (p_list_pre != NULL) {
		  p_list_pre->p_next = p_list->p_next;
		} else {
		  set_node_addr(p_mem_list, i, NULL);
		}
		frees(p_list);
	  } else {                          // 节点未空
            // 整体移动后续元素
            i_start = k;
            p_list_tail = p_list;
            p_list_last = p_list;
            while(p_list != NULL) {
			  for (m = i_start; m <= get_list_num(p_list); m++){
                    if (m < (UNIT_NUMBER - 1)) {
					  set_node_addr(p_list, m, get_node_addr(p_list, m+1));
                    } else {
                        if (p_list->p_next != NULL) {
							set_node_addr(p_list, m, get_node_addr(p_list, 1));
                        }
                    }
                }
                i_start = 1;
                if (p_list->p_next != NULL) {
                    if (p_list->p_next->p_next == NULL) {
                        p_list_tail = p_list;
                    }
                }
                p_list_last = p_list;
                p_list = p_list->p_next;
            }
			set_list_num(p_list_last, get_list_num(p_list_last) - 1);
            if (get_list_num(p_list_last) <= 0){
                if (p_list_tail->p_next == NULL) {
					set_node_addr(p_mem_list, i, NULL);
                } else {
                    p_list_tail->p_next = NULL;
                }
                frees(p_list_last);
            }
        }
    }
    
    return 0;
 error_tray: // 错误处理
    fprintf(stderr,                        // 错误输出
            "mem_list_del 中发生错误,错误号: [ %d ].", i_err);
    return i_err;
}

// 从在用或者空闲内存链表中根据起始内存地址查找节点
int mem_list_get_bas(x_mem_pool_t *p_mem_pool, // 内存池对象
					int i_list_type,          // 内存链表类型:0,空闲:1,在用.
					void * p_addr_req)        // 待查找的内存地址
{
    int i_err = 0;
	int i = 0;
	int m = 0;
	int i_flag = 0;

    x_mem_block_t *p_list = NULL;

    x_mem_block_t *p_mem_list = NULL;

    // 参数合法性检测
    if (p_mem_pool == NULL)                // 如果内存池对象不存在
        { i_err = ERR_MP_PARAM; goto error_tray; }
	if (p_addr_req == NULL)                // 如果待查内存地址为空
	  { i_err = ERR_MP_PARAM; goto error_tray; }
    switch (i_list_type){                  // 内存链表类型检测
    case 0:
        p_mem_list = p_mem_pool->p_mem_free_list;
        break;
    case 1:
        p_mem_list = p_mem_pool->p_mem_used_list;
        break;
    default:
        { i_err = ERR_MP_PARAM; goto error_tray; }
    }

	// 遍历内存列表,进行查找
	i_flag = 0;
	for(i = 0; i < UNIT_NUMBER; i++) {
	  p_list = (x_mem_block_t*)get_node_addr(p_mem_list, i);
	  while(p_list != NULL){
		for(m = 1; m <= get_list_num(p_list); m++){
		  if( get_node_addr(p_list, m) == p_addr_req){
			i_flag = (i+1);
			goto normal_exit;
		  }
		}
		p_list = p_list->p_next;
	  }
	}
 normal_exit:
    return i_flag;
 error_tray: // 错误处理
    fprintf(stderr,                        // 错误输出
            "mem_list_get_bas 中发生错误,错误号: [ %d ].", i_err);
    return i_err;
}


// 从在用或者空闲内存链表中根据结束内存地址查找节点
int mem_list_get_bae(x_mem_pool_t *p_mem_pool, // 内存池对象
					int i_list_type,          // 内存链表类型:0,空闲:1,在用.
					void * p_addr_req)        // 待查找的内存地址
{
    int i_err = 0;
	int i = 0;
	int m = 0;
	int i_flag = 0;

    x_mem_block_t *p_list = NULL;

    x_mem_block_t *p_mem_list = NULL;

    // 参数合法性检测
    if (p_mem_pool == NULL)                // 如果内存池对象不存在
        { i_err = ERR_MP_PARAM; goto error_tray; }
	if (p_addr_req == NULL)                // 如果待查内存地址为空
	  { i_err = ERR_MP_PARAM; goto error_tray; }
    switch (i_list_type){                  // 内存链表类型检测
    case 0:
        p_mem_list = p_mem_pool->p_mem_free_list;
        break;
    case 1:
        p_mem_list = p_mem_pool->p_mem_used_list;
        break;
    default:
        { i_err = ERR_MP_PARAM; goto error_tray; }
    }

	// 遍历内存列表,进行查找
	i_flag = 0;
	for(i = 0; i < UNIT_NUMBER; i++) {
	  p_list = (x_mem_block_t*)get_node_addr(p_mem_list, i);
	  while(p_list != NULL){
		for(m = 1; m <= get_list_num(p_list); m++){
		  if((get_node_addr(p_list, m)+ (i+ 1)*sizeof(UNIT_TYPE)) == p_addr_req){
			i_flag = (i+1);
			goto normal_exit;
		  }
		}
		p_list = p_list->p_next;
	  }
	}

 normal_exit:     
    return i_flag;
 error_tray: // 错误处理
    fprintf(stderr,                        // 错误输出
            "mem_list_get_bae 中发生错误,错误号: [ %d ].", i_err);
    return i_err;
}


// 从在用或者空闲内存链表中根据结束内存地址查找节点
int mem_list_get_bsz(x_mem_pool_t *p_mem_pool, // 内存池对象
					int i_list_type,           // 内存链表类型:0,空闲:1,在用.
					 int i_unit_number,        // 待查找的内存单元大小
					 void **p_out_addr)        // 返回地址  
{
    int i_err = 0;
	int i = 0;
	int m = 0;
	int i_flag = 0;

    x_mem_block_t *p_list = NULL;

    x_mem_block_t *p_mem_list = NULL;

    // 参数合法性检测
    if (p_mem_pool == NULL)                // 如果内存池对象不存在
        { i_err = ERR_MP_PARAM; goto error_tray; }

	// 如果待查内存单元大小为0
	if ((i_unit_number <= 0) || (i_unit_number > UNIT_NUMBER))
	  { i_err = ERR_MP_PARAM; goto error_tray; }

    switch (i_list_type){                  // 内存链表类型检测
    case 0:
        p_mem_list = p_mem_pool->p_mem_free_list;
        break;
    case 1:
        p_mem_list = p_mem_pool->p_mem_used_list;
        break;
    default:
        { i_err = ERR_MP_PARAM; goto error_tray; }
    }

	// 遍历内存列表,进行查找
	i_flag = 0;
	for(i = i_unit_number; i < UNIT_NUMBER; i++) {
	  p_list = (x_mem_block_t*)get_node_addr(p_mem_list, i);
	  if(p_list != NULL){
		if (get_list_num(p_list) > 0){
		  i_flag = i + 1;
		  *p_out_addr = get_node_addr(p_list, 1);
		  break;
		}
	  }
	}
	
	return i_flag;
 error_tray: // 错误处理
    fprintf(stderr,                        // 错误输出
            "mem_list_get_bsz 中发生错误,错误号: [ %d ].", i_err);
    return i_err;
}

// 创建内存池对象,并初始化相关数据
x_mem_pool_t *create_mem_pool(int *p_errno)
{
  int i = 0;
  
  x_mem_pool_t *p_mem_pool = NULL;
  
  x_mem_block_t *p_mem_free_list = NULL;
  x_mem_block_t *p_mem_used_list = NULL;

  p_mem_free_list = (x_mem_block_t*)mallocs(sizeof(x_mem_block_t));
  if (p_mem_free_list == NULL){
    fprintf(stderr,                        // 错误输出
            "create_mem_pool 中发生错误,内存不足.");
	*p_errno = ERR_MP_NOMEM;
	return NULL;
  }

  p_mem_used_list = (x_mem_block_t*)mallocs(sizeof(x_mem_block_t));
  if (p_mem_used_list == NULL){
    fprintf(stderr,                        // 错误输出
            "create_mem_pool 中发生错误,内存不足.");
	if(p_mem_free_list != NULL) frees(p_mem_free_list);
	*p_errno = ERR_MP_NOMEM;
	return NULL;
  } 

  
  p_mem_pool = (x_mem_pool_t*)mallocs(sizeof(x_mem_block_t));
  if (p_mem_pool == NULL){
    fprintf(stderr,                        // 错误输出
            "create_mem_pool 中发生错误,内存不足.");
	if(p_mem_free_list != NULL) frees(p_mem_free_list);
	if(p_mem_used_list != NULL) frees(p_mem_used_list);
	*p_errno = ERR_MP_NOMEM;
	return NULL;
  }
  p_mem_pool->p_block = NULL;
  p_mem_pool->p_mem_free_list = p_mem_free_list;
  p_mem_pool->p_mem_used_list = p_mem_used_list;

  for(i = 0; i < UNIT_NUMBER; i++){
	set_node_addr(p_mem_pool->p_mem_free_list, i, NULL);
  }
  for(i = 0; i < UNIT_NUMBER; i++){
	set_node_addr(p_mem_pool->p_mem_used_list, i, NULL);
  }

  return p_mem_pool;
}

// 内存分配
void *mem_alloc(x_mem_pool_t *p_mem_pool, int i_size, int *p_errno)
{
  int i_unit_number = 0;
  int i_ret = 0;

  void *p_addr_got = NULL;
  x_mem_block_t *p_mem_blk_new = NULL;
  x_mem_block_t *p_mem_blk = NULL;
  x_mem_block_t *p_mem_blk_tail = NULL;

  // 参数合法性检测
  if (p_mem_pool == NULL) {*p_errno = ERR_MP_PARAM;return NULL;}
  if ((i_size <=0) || (i_size >UNIT_NUMBER * sizeof(UNIT_TYPE))){
	*p_errno = ERR_MP_PARAM;return NULL;
  }
  
  i_unit_number = (i_size / sizeof(UNIT_TYPE)) + // 计算字节数
	(((i_size % sizeof(UNIT_TYPE)) != 0) ? 1 : 0);

  i_ret =                                        // 查找空闲内存
	mem_list_get_bsz(p_mem_pool,0, i_unit_number, &p_addr_got);
  if (i_ret <= 0){                               // 如果未找到
	p_mem_blk_new = (x_mem_block_t*)mallocs(sizeof(x_mem_block_t));
	if (p_mem_blk_new == NULL) {
	  *p_errno = ERR_MP_NOMEM;return NULL;
	}
	p_mem_blk_new->p_next = NULL;
	p_addr_got = (void*)(p_mem_blk_new->unit_array);
	i_ret = UNIT_NUMBER;
	if(p_mem_pool->p_block == NULL){             // 内存池中尚未分配内存块
	  p_mem_pool->p_block = p_mem_blk_new;       // 链接新内存块
	} else {                                     // 或者已分配了内存块
	  p_mem_blk = p_mem_blk_tail = p_mem_pool->p_block;
	  while(p_mem_blk != NULL){
		p_mem_blk_tail = p_mem_blk;
		p_mem_blk = p_mem_blk->p_next;
	  }
	  p_mem_blk_tail->p_next = p_mem_blk_new;    // 链接新内存块
	}
  } else {                                       // 空闲内存块已找到
    printf("找到的待删除空闲内存地址是：%x\r\n", p_addr_got);
	mem_list_del(p_mem_pool, 0, p_addr_got);     // 删除该空闲块
  }

  int i_unit_number_new = 0;
  void *p_addr_new = NULL;

  if (i_unit_number < i_ret){ // 如果需要拆分该块空闲内存
	p_addr_new = p_addr_got + i_unit_number * sizeof(UNIT_TYPE);
	i_unit_number_new = i_ret - i_unit_number;
	// 注册拆分后得到的新的空闲内存
	mem_list_add(p_mem_pool, 0, p_addr_new, i_unit_number_new);
  }
  // 注册新的在用内存
  mem_list_add(p_mem_pool, 1, p_addr_got, i_unit_number);
  
  return p_addr_got;

}

// 内存释放
int mem_free(x_mem_pool_t *p_mem_pool, void *p_addr_req)
{
  int i_err = 0;
  int i_ret = 0;

  int i_unit_number = 0;

  int i_size_f = 0;
  int i_size_e = 0;
  void *p_addr_f = NULL;
  void *p_addr_e = NULL;

  void *p_free = NULL;
  x_mem_block_t *p_blk = NULL;
  x_mem_block_t *p_blk_p = NULL;
  x_mem_block_t *p_blk_n = NULL;

  // 参数合法性检测.
  if (p_mem_pool == NULL)                // 如果内存池对象不存在
	{ i_err = ERR_MP_PARAM; goto error_tray; }
  if (p_addr_req == NULL)                // 如果内存地址为NULL
        { i_err = ERR_MP_PARAM; goto error_tray; }
  
  // 查找相应的内存大小
  i_ret = mem_list_get_bas(p_mem_pool,1,p_addr_req);
  if (i_ret <= 0) {
	 i_err = ERR_MP_NOOBJ; goto error_tray;
  }
  i_unit_number = i_ret;

  mem_list_del(p_mem_pool,1,p_addr_req);

  // 取得融合地址下位地址
  i_ret = mem_list_get_bas(p_mem_pool, 0, p_addr_req + i_unit_number*sizeof(UNIT_TYPE));
  if (i_ret < 0) i_ret = 0;
  i_size_e = i_ret;
  p_addr_e = p_addr_req + i_unit_number*sizeof(UNIT_TYPE) - 1 + i_size_e*sizeof(UNIT_TYPE);
  if (i_ret > 0) {
	mem_list_del(p_mem_pool, 0, p_addr_req + i_unit_number*sizeof(UNIT_TYPE));
  }

  // 取得融合地址高位地址
  i_ret = mem_list_get_bae(p_mem_pool, 0, p_addr_req);
  if (i_ret < 0) i_ret = 0;
  i_size_f = i_ret;
  p_addr_f = p_addr_req - i_size_f*sizeof(UNIT_TYPE);
  if (i_ret > 0) {
	mem_list_del(p_mem_pool, 0, p_addr_f);
  }
  
  // 如果该空间大小正好等于一个内存块大小
  if ((i_size_f + i_unit_number +i_size_e) == UNIT_NUMBER){
	// 释放该内存块
	p_free = 
	  p_addr_f +  sizeof(x_mem_block_t) - sizeof(UNIT_TYPE[UNIT_NUMBER]) - 1;
	p_blk = p_mem_pool->p_block;
	p_blk_p = p_blk;
	while(p_blk != NULL){
	  if (p_blk == p_free) {
	    break;
	  }
	  p_blk_p = p_blk;
	  p_blk = p_blk->p_next;
	}
	
	if (p_blk != NULL) {
	  p_blk_p->p_next = p_blk->p_next;
	  if (p_blk == p_mem_pool->p_block){
	    p_mem_pool->p_block = NULL;
	  }
	  frees(p_free);
	}
	

  } else {
	// 注册新的融合后的空闲内存
	mem_list_add(p_mem_pool, 0, p_addr_f, i_size_f + i_unit_number + i_size_e);
  }
 
  return 0;
 error_tray:
    fprintf(stderr,                        // 错误输出
            "mem_free 中发生错误,错误号: [ %d ].", i_err);
  return i_err;
}

// 内存池重置清零
int mem_pool_reset(x_mem_pool_t *p_mem_pool)
{

  int i = 0;

  x_mem_block_t *p_blk = NULL;
  x_mem_block_t *p_list = NULL;
  x_mem_block_t *p_temp = NULL;

  p_blk = p_mem_pool->p_mem_free_list;
  for (i = 0; i < UNIT_NUMBER; i++){
    p_list = (x_mem_block_t*)(get_node_addr(p_blk, i));
    while(p_list != NULL){
      p_temp = p_list->p_next;
      frees(p_list);
      p_list=p_temp;
    }
	set_node_addr(p_blk, i, NULL);
  }

  p_blk = p_mem_pool->p_mem_used_list;
  for (i = 0; i < UNIT_NUMBER; i++){
    p_list = (x_mem_block_t*)(get_node_addr(p_blk, i));
    while(p_list != NULL){
      p_temp = p_list->p_next;
      frees(p_list);
      p_list=p_temp;
    }
	set_node_addr(p_blk, i, NULL);
  }

  p_blk = p_mem_pool->p_block;
  while(p_blk != NULL){
    p_temp = p_blk->p_next;
    frees(p_blk);
    p_blk=p_temp;
  }
  p_mem_pool->p_block = NULL;
  return 0;
}

// 销毁内存池对象
int destroy_mem_pool(x_mem_pool_t *p_mem_pool)
{
  if (p_mem_pool == NULL) {return ERR_MP_PARAM;}
  mem_pool_reset(p_mem_pool);
  frees(p_mem_pool->p_mem_free_list);
  frees(p_mem_pool->p_mem_used_list);
  frees(p_mem_pool);
  return 0;
}

// 打印内存分布现状等等信息
int mem_pool_print(x_mem_pool_t *p_mp, int b_only_total)
{
  x_mem_block_t *p_blk = NULL;
  x_mem_block_t *p_list = NULL;
  x_mem_block_t *p_list_sub = NULL;
  int m = 0, n = 0, cnt = 0, i = 0;

  int i_block_num = 0;
  int i_size_used = 0;
  int i_size_free = 0;
  int i_free_list_num = 0;
  int i_used_list_num = 0;



  // 遍历used_list
  if(!b_only_total)
	printf("======================> Now printing used list:\n");
  p_list = p_mp->p_mem_used_list;
  for(m = 0; m < UNIT_NUMBER; m++){
	p_list_sub = get_node_addr(p_list,m);
	if(!b_only_total)
	  printf("------------------ new sub[size:%d UNIT] ------------------\n", m+1);
	while(p_list_sub != NULL) {
	  cnt = get_list_num(p_list_sub);
	  if (cnt > 0) {
		if(!b_only_total)
		  printf("new serial, total %d\n", cnt);
		for(i = 1; i <= cnt; i++){
		  if(!b_only_total)
			printf("address of memory:[%p]\n", get_node_addr(p_list_sub, i));
		  i_size_used += (m+1);
		}
	  }
	  p_list_sub = p_list_sub->p_next;
	  i_used_list_num += 1;
	}
  }

  // 遍历free_list
  if(!b_only_total)
	printf("======================> Now printing free list:\n");
  p_list = p_mp->p_mem_free_list;
  for(m = 0; m < UNIT_NUMBER; m++){
	p_list_sub = get_node_addr(p_list,m);
	if(!b_only_total)
	  printf("------------------ new sub[size:%d UNIT] ------------------\n", m+1);
	while(p_list_sub != NULL) {
	  cnt = get_list_num(p_list_sub);
	  if (cnt > 0) {
		if(!b_only_total)
		  printf("new serial, total %d\n", cnt);
		for(i = 1; i <= cnt; i++){
		  if(!b_only_total)
			printf("address of memory:[%p]\n", get_node_addr(p_list_sub, i));
		  i_size_free += (m+1);
		}
	  }
	  p_list_sub = p_list_sub->p_next;
	  i_free_list_num += 1;
	}
  }

  p_blk = p_mp->p_block;
  while(p_blk != NULL){
	i_block_num += 1;
	p_blk = p_blk->p_next;
  }
  
  printf("总计: 在用内存[%d]字节,未用内存[%d]字节,全部内存块共计[%d]字节; 在用内存列表[%d]个,未用内存列表[%d]个.\n",
		 i_size_used * UNIT_LEN,
		 i_size_free * UNIT_LEN,
		 i_block_num * UNIT_NUMBER * UNIT_LEN,
		 i_used_list_num,
		 i_free_list_num);
  
}

//--------------------------------  end  --------------------------------
